package com.autumn.platform.dao.schema.statement.original;

import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.session.Configuration;

import com.autumn.platform.dao.schema.parser.SchemaSqlMapperParserDelegate;
import com.autumn.platform.dao.schema.statement.StatementHandlerSupport;

public class SqlStatementHandler extends StatementHandlerSupport {

    @Override
    public void handleStatementNode(Configuration configuration, SchemaSqlMapperParserDelegate delegate, XNode node) {
        String databaseId = configuration.getDatabaseId();
        if (databaseId != null) {
            sqlElement(configuration, delegate, node, databaseId);
        }
        sqlElement(configuration, delegate, node, null);
    }

    private void sqlElement(Configuration configuration, SchemaSqlMapperParserDelegate delegate, XNode context, String requiredDatabaseId) {
        String databaseId = context.getStringAttribute("databaseId");
        String id = context.getStringAttribute("id");
        id = delegate.getBuilderAssistant().applyCurrentNamespace(id, false);
        if (databaseIdMatchesCurrent(configuration, id, databaseId, requiredDatabaseId)) {
            configuration.getSqlFragments().put(id, context);
        }
    }

    private boolean databaseIdMatchesCurrent(Configuration configuration, String id, String databaseId, String requiredDatabaseId) {
        if (requiredDatabaseId != null) {
            if (!requiredDatabaseId.equals(databaseId)) {
                return false;
            }
        } else {
            if (databaseId != null) {
                return false;
            }
            // skip this fragment if there is a previous one with a not null
            // databaseId
            if (configuration.getSqlFragments().containsKey(id)) {
                XNode context = configuration.getSqlFragments().get(id);
                if (context.getStringAttribute("databaseId") != null) {
                    return false;
                }
            }
        }
        return true;
    }
}
